package com.baic.ibase.service.users.impl;

import com.alibaba.fastjson2.JSON;
import com.baic.ibase.mapper.*;
import com.baic.ibase.models.dao.*;
import com.baic.ibase.models.req.common.ApiResponse;
import com.baic.ibase.models.req.common.PageResponse;
import com.baic.ibase.models.req.users.CreateUserReq;
import com.baic.ibase.models.req.users.ListUsersByPageReq;
import com.baic.ibase.models.vo.PermissionVo;
import com.baic.ibase.models.vo.RolePermissionVo;
import com.baic.ibase.models.vo.UserInfo;
import com.baic.ibase.service.users.UsersService;
import com.baic.ibase.utils.token.TokenUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Slf4j
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService {


    @Autowired
    private UsersMapper usersMapper;


    @Autowired
    private UsersRolesMapper usersRolesMapper;
    @Autowired
    private RolesMapper rolesMapper;
    @Autowired
    private RolesPermissionsMapper rolesPermissionsMapper;
    @Autowired
    private PermissionsMapper permissionsMapper;


    @Override
    public ApiResponse<PageResponse<Users>> listUsersByPage(ListUsersByPageReq req) {
        ApiResponse<PageResponse<Users> > commonResponse = ApiResponse.ok();

        PageResponse<Users> pageResponse = new PageResponse<>();
        try {
            log.info("listUsersByPage req:{}", JSON.toJSONString(req));
            IPage<Users> page = new Page<>(req.getPageNum(), req.getPageSize());
            LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();

            queryWrapper.eq(!Strings.isBlank(req.getUsername()), Users::getUsername, req.getUsername());

            IPage<Users> usersIPage = usersMapper.selectPage(page, queryWrapper);

            pageResponse.setData(usersIPage.getRecords());
            pageResponse.setTotal(usersIPage.getTotal());
            pageResponse.setPages((int) usersIPage.getPages());
            pageResponse.setPageNum((int) usersIPage.getCurrent());
            pageResponse.setPageSize((int) usersIPage.getSize());
            pageResponse.setRequestId(req.getRequestId());

            commonResponse.setData(pageResponse);
            log.info("listUsersByPage pageResponse:{}", pageResponse);

        } catch (Exception e) {
            commonResponse = ApiResponse.error(500, "listUsersByPage error");
            log.error("listUsersByPage error:{}", e.getMessage());
            e.printStackTrace();
        }

        return commonResponse;
    }

    @Override
    public ApiResponse<Users> saveUsers(CreateUserReq req) {
        Users users = new Users();
        users.setUsername(req.getUsername());
        users.setNickname(req.getNickname());
        users.setPhone(req.getPhone());
        users.setPassword(req.getPassword());
        users.setStatus(1);
        users.setCreatedUserId(1L);
        users.setUpdatedUserId(1L);
        users.setCreatedTime(LocalDateTime.now());
        users.setUpdatedTime(LocalDateTime.now());

        if (save(users)) {
            log.info("saveUsers users:{}", users);
            return ApiResponse.ok(users);
        } else {
            log.error("saveUsers error");
            return ApiResponse.error(500, "添加用户失败");
        }
    }

    @Override
    public ApiResponse<UserInfo> getInfoByToken(String token) {
        ApiResponse<UserInfo> resp = ApiResponse.ok();

        if (token != null) {
            if (TokenUtils.verify( token)) {
                UserInfo userInfo = new UserInfo();
                String userId = TokenUtils.getUserId(token);
                String userName = TokenUtils.getUserName(token);

                Users byId = this.getById(userId);
                if (byId != null) {
                    userInfo.setId(byId.getId());
                    userInfo.setUserName(byId.getUsername());
                    userInfo.setStatus(byId.getStatus());
                    userInfo.setAvatar(byId.getAvatar());
                    userInfo.setPhone(byId.getPhone());

                    LambdaQueryWrapper<UsersRoles> usersRolesMapperLambdaQueryWrapper = new LambdaQueryWrapper<UsersRoles>()
                        .eq(UsersRoles::getUsersId, userId);

                    UsersRoles usersRoles = usersRolesMapper.selectOne(usersRolesMapperLambdaQueryWrapper);
                    if (usersRoles != null) {
                        RolePermissionVo rolePermissionVo = new RolePermissionVo();
                        userInfo.setRoleId(usersRoles.getRolesId());
                        // 获取角色信息
                        LambdaQueryWrapper<Roles> rolesMapperLambdaQueryWrapper = new LambdaQueryWrapper<Roles>().eq(Roles::getId, usersRoles.getRolesId());
                        Roles roles = rolesMapper.selectOne(rolesMapperLambdaQueryWrapper);
                        rolePermissionVo.setId(roles.getId());
                        rolePermissionVo.setRoleCode(roles.getRoleCode());
                        rolePermissionVo.setRoleName(roles.getRoleName());


                        // 查询角色对应的权限
                        LambdaQueryWrapper<RolesPermissions> rolesPermissionsLambdaQueryWrapper = new LambdaQueryWrapper<RolesPermissions>()
                                .eq(RolesPermissions::getRolesId, roles.getId());

                        List<RolesPermissions> rolesPermissions = rolesPermissionsMapper.selectList(rolesPermissionsLambdaQueryWrapper);

                        List<PermissionVo> permissionVos = new ArrayList<>();

                        // todo: 存储redis
                        if (rolesPermissions != null) {
                            rolesPermissions.forEach(rolesPermission -> {
                                PermissionVo permissionVo = new PermissionVo();
                                Permissions permissions = permissionsMapper.selectById(rolesPermission.getPermissionId());

                                if (permissions != null) {
                                    permissionVo.setRoleId(rolesPermission.getRolesId());
                                    permissionVo.setPermissionId(permissions.getId());
                                    permissionVo.setPermissionCode(permissions.getPermissionCode());
                                    permissionVo.setPermissionName(permissions.getPermissionName());
                                    permissionVos.add(permissionVo);
                                }
                            });
                        }

                        rolePermissionVo.setPermissions(permissionVos);
                        userInfo.setRoles(rolePermissionVo);

                    }
                }
                resp.setData(userInfo);
            }
        }
        return resp;
    }
}
